type name = string
type age = int
type adress = string
type telephone = int
type contact = (name * age * adress * telephone)
type agenda = contact list

let rec exist x = function
      [] -> false
     |e::l -> if e = x then 
              true
            else
              exist x l ;;

let rec add_list x = function
   [] -> x::[]
  |e::l -> if e<x then
               e::add_list x l
            else
               x::e::l ;;

let rec remove_list x = function
   [] -> invalid_arg "element not found"
  |e::l -> if e=x then 
               l
            else 
               e::remove_list x l ;;

let rec map f = function 
   [] -> []
  |e::l -> f e::map f l ;;

let rec iter f = function
   [] -> ()
  |e::l -> (f e;iter f l) ;;

let rec for_all f = function 
  [] -> true
  |e::l -> f e &&  for_all f l;;

let upper_case x = if x >= 'a' && x<= 'z' then
                         char_of_int (int_of_char x - 32)
                    else 
                         x ;;

let lower_case x = if x >= 'A' && x <= 'Z' then
                         char_of_int (int_of_char x + 32)
                    else 
                         x ;;

let string_of_char c = String.make 1 c ;;

let string_apply f chaine =
  let rec apply = function
       c when c = (String.length chaine) -> ""
      |c ->  string_of_char (f chaine.[c]) ^ (apply (c+1))
          in apply 0 ;;
 
      
        
let string_uppercase = string_apply (upper_case) ;;

let string_lowercase = string_apply (lower_case) ;;

let convert_first_maj chaine =
  let rec first_maj = function
     x when x = (String.length chaine) -> ""
    |x when x = 0 -> string_of_char(upper_case chaine.[0]) ^ first_maj (x+1)
    |x -> string_of_char (lower_case chaine.[x]) ^ first_maj (x+1)
  in first_maj 0 ;;


let create_contact(name,a,b,c) = convert_first_maj name, a, b, c ;;

let manage_contact f contact agenda = f contact agenda ;;

let rec add_contact (name,a,b,c) liste = match liste with
       [] -> liste 
      |(n,d,e,f)::l -> if string_lowercase n < string_lowercase name then
                            (n,d,e,f)::add_contact (name,a,b,c) l
          	         else
                            if string_lowercase name = string_lowercase n then
                                    invalid_arg "contact already exists"
                              else
                                    (name,a,b,c)::(n,d,e,f)::l ;;    

